package org.itboys.pay.weixin;

import java.io.UnsupportedEncodingException;
import java.security.SignatureException;
import java.util.Map;

import org.apache.commons.codec.digest.DigestUtils;
import org.itboys.pay.alipay.AlipayCore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 微信支付异步回调签名校验
 * @author huml
 *
 */
public class WXPayNotify {
	private static  Logger logger = LoggerFactory.getLogger(WXPayNotify.class);
    /**
     * 验证sign
     * @param params 通知返回来的参数数组
     * @return 验证结果
     */
    public static boolean verifyNotify(Map<String, String> params, String key) {
	    String sign = "";
	    //获取返回时的签名验证结果
	    if(params.get("sign") != null) {sign = params.get("sign");}
	    //验证签名
	    boolean isSign = getSignVeryfy(params, sign, true,  key);
        //判断isSign是否为true
        //isSign不是true，与安全校验码、请求时的参数格式（如：带自定义参数等）、编码格式有关
        if (isSign) {
            return true;
        } else {
            return false;
        }
    }
    /**
     * 根据反馈回来的信息，生成签名结果
     * @param Params 通知返回来的参数数组
     * @param sign 比对的签名结果
     * @param isSort 是否排序
     * @return 生成的签名结果
     */
	private static boolean getSignVeryfy(Map<String, String> Params, String sign, boolean isSort, String payKey) {
    	//过滤空值、sign与sign_type参数
    	Map<String, String> sParaNew = AlipayCore.paraFilter(Params);
        //获取待签名字符串
    	String preSignStr = "";
    	if(isSort) {
    		preSignStr = AlipayCore.createLinkString(sParaNew);
    	} else {
//    		preSignStr = AlipayCore.createLinkStringNoSort(sParaNew);
    		for (String key : sParaNew.keySet()) {
    			preSignStr = preSignStr + key + "=" + sParaNew.get(key) + "&";
       	 }
    		preSignStr = preSignStr.substring(0,preSignStr.length()-1);
    	}
        //获得签名验证结果
        boolean isSign = false;
        isSign = verify(preSignStr, sign,"&key="+payKey,"utf-8");
        return isSign;
    }
    private static boolean verify(String text, String sign, String key, String input_charset) {
    	text = text + key;
    	String mysign = DigestUtils.md5Hex(getContentBytes(text, input_charset)).toUpperCase();
    	if(mysign.equals(sign)) {
    		return true;
    	}
    	else {
    		logger.info(text);
    		logger.info("*******************sign="+sign+";--mySign="+mysign);
    		return false;
    	}
    }
    /**
     * @param content
     * @param charset
     * @return
     * @throws SignatureException
     * @throws UnsupportedEncodingException 
     */
    private static byte[] getContentBytes(String content, String charset) {
        if (charset == null || "".equals(charset)) {
            return content.getBytes();
        }
        try {
            return content.getBytes(charset);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("MD5签名过程中出现错误,指定的编码集不对,您目前指定的编码集是:" + charset);
        }
    }
}
